# -*- coding: utf-8 -*-
# 标准库导入
import sys, os, time
import win32gui
import win32con
import win32process
import subprocess
from threading import Thread
# 第三方库导入
from PyQt5.QtCore import Qt, pyqtSignal, QThread
from PyQt5.QtWidgets import (
    QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout,
    QLabel, QLineEdit, QPushButton, QTableWidget, QTableWidgetItem,
    QHeaderView, QMessageBox, QStackedWidget, QComboBox, QFormLayout,
    QDialog, QDialogButtonBox, QStyleFactory, QGraphicsDropShadowEffect,
    QSizePolicy, QButtonGroup
)

from PyQt5.QtGui import QFont, QIcon, QPixmap, QColor, QDoubleValidator, QIntValidator
from tqsdk import TqApi, TqAuth, TqAccount, TqSim, TqKq

# 本地模块导入
# 修改导入语句
from database_utils_stable04_01 import (
    connect_db,
    get_all_products,
    insert_product,
    update_product,
    delete_product,
    get_monitored_products,
    delete_product_by_name,
    get_product_by_id
)
import asyncio
from qasync import asyncSlot, QEventLoop
import psutil
import sqlite3


class CapitalManager(QMainWindow):
    # 添加全局设置页面索引
    PAGE_INDEX = {
        "CALCULATE": 0,
        "ORDER": 1,
        "PRODUCT_MGMT": 2,
        "GLOBAL_SETTINGS": 3,  # 新增全局设置页面索引
        "AUTO_SL": 4,
        "HELP": 5   
    }

    def __init__(self):
        super().__init__()
        self.thread = None  # 新增线程引用
        # 新增线程终止标志
        self._shutting_down = False
        self.init_data()  # 这个调用已经存在
        self.init_ui()
        self.setup_connections()
        self.setWindowTitle("资金管理系统")
        self.resize(1500, 1000)
        self.handle_page_change(0)
        self.process_id = None
        self.worker_thread = None
        self.connect_tq()  # 启动时，自动连接天勤账户
        self.exe_path = None

    def init_data(self):
        """初始化核心数据"""
        # 连接成功后加载监控品种
        conn = connect_db()
        if conn:
            # 获取监控中的品种（is_monitored=1）
            self.products = [
                {
                    'name': p[1],
                    'margin': p[3],
                    'stoploss': p[4],
                    'exchange_code': p[2],
                    'limit_stoploss': p[7]
                }
                for p in get_monitored_products(conn)
                if p[6]  # 第7个字段是is_monitored
            ]
            conn.close()
        else:
            self.products = []

        self.api = None  # 天勤API连接实例
        self.account = None  # 交易账户信息

    def init_ui(self):
        # ==== 主布局 ====
        main_widget = QWidget()
        main_h_layout = QHBoxLayout(main_widget)

        # ==== 左侧面板 ====
        side_panel = self._init_side_panel()

        # ==== 右侧堆叠窗口 ====
        self.stacked_widget = QStackedWidget()
        # 统一使用 addWidget 按顺序添加
        self.stacked_widget.addWidget(self._init_capital_ui())  # 索引0
        self.stacked_widget.addWidget(self._init_order_ui())  # 索引1
        self.stacked_widget.addWidget(self._init_product_management_ui())  # 索引2
        self.stacked_widget.addWidget(self._init_global_settings_ui())  # 新增全局设置页面 索引3
        self.stacked_widget.addWidget(self._init_auto_sl_ui())  # 索引4
        self.stacked_widget.addWidget(self._init_help_ui())  # 索引5

        main_h_layout.addWidget(side_panel)
        main_h_layout.addWidget(self.stacked_widget, stretch=1)
        self.setCentralWidget(main_widget)

    def _init_side_panel(self):
        """统一初始化侧边栏"""
        panel = QWidget()
        layout = QVBoxLayout(panel)

        # 新增按钮组初始化
        self.nav_btns = QButtonGroup(self)
        self.nav_btns.setExclusive(True)  # 确保按钮互斥

        button_config = [
            ("计算下单量", self.PAGE_INDEX["CALCULATE"]),
            ("下单", self.PAGE_INDEX["ORDER"]),
            ("品种管理", self.PAGE_INDEX["PRODUCT_MGMT"]),
            ("全局设置", self.PAGE_INDEX["GLOBAL_SETTINGS"]),  # 新增全局设置按钮
            ("启动策略交易", self.PAGE_INDEX["AUTO_SL"]),
            ("帮助中心", self.PAGE_INDEX["HELP"])
        ]

        # 确保 PAGE_INDEX 与实际索引一致
        self.PAGE_INDEX = {
            "CALCULATE": 0,
            "ORDER": 1,
            "PRODUCT_MGMT": 2,
            "GLOBAL_SETTINGS": 3,
            "AUTO_SL": 4,
            "HELP": 5
        }

        self.side_buttons = []
        for idx, (text, page_id) in enumerate(button_config):
            btn = QPushButton(text)
            btn.setCheckable(True)
            btn.setMinimumSize(200, 40)
            # 更新为经典立体样式
            btn.setStyleSheet("""
                QPushButton {
                    text-align: center;
                    padding: 12px 25px;
                    border: 1px solid #a0a0a0;
                    border-radius: 4px;
                    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                        stop:0 #f6f7fa, stop:1 #e0e1e5);
                    font: 13px "微软雅黑";  /* 移除默认粗体 */
                    color: #505050;
                }
                QPushButton:checked, QPushButton:pressed {
                    font-weight: bold;  /* 仅在选中/按下时加粗 */
                }
                QPushButton:hover {
                    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                        stop:0 #e3e7ef, stop:1 #d4d7dc);
                }
                QPushButton:checked {
                    background: #e3f2fd;
                    border: 1px solid #2196F3;
                    color: #1565C0;
                }
                QPushButton:pressed {
                    background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                        stop:0 #d0d0d0, stop:1 #e0e0e0);
                }
            """)
            btn.clicked.connect(lambda _, x=page_id: self._handle_side_button_click(x))
            layout.addWidget(btn)
            self.side_buttons.append(btn)
            self.nav_btns.addButton(btn, idx)

        # 设置默认选中第一个按钮
        self.side_buttons[0].setChecked(True)

        layout.addStretch()
        return panel

    def _handle_side_button_click(self, page_index):
        self.stacked_widget.setCurrentIndex(page_index)
        for btn in self.side_buttons:
            if self.nav_btns.id(btn) == page_index:
                btn.setChecked(True)
            else:
                btn.setChecked(False)

    def _init_capital_ui(self):
        """资金管理页面初始化"""
        widget = QWidget()
        layout = QVBoxLayout(widget)

        # 显示账户资金信息
        capital_label = QLabel("账户可用资金:")
        self.capital_value_label = QLabel("加载中...")
        self.update_signal.connect(self.capital_value_label.setText)

        # 资金输入框
        input_layout = QHBoxLayout()
        input_label = QLabel("输入资金金额:")
        self.capital_input = QLineEdit()
        self.capital_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        input_btn = QPushButton("更新资金")
        input_btn.clicked.connect(self._update_capital)

        input_layout.addWidget(input_label)
        input_layout.addWidget(self.capital_input)
        input_layout.addWidget(input_btn)

        layout.addWidget(capital_label)
        layout.addWidget(self.capital_value_label)
        layout.addLayout(input_layout)
        layout.addStretch()

        return widget

    def _update_capital(self):
        """更新账户资金"""
        try:
            new_capital = float(self.capital_input.text())
            # 这里可以添加更新数据库或其他操作的逻辑
            print(f"更新账户资金为: {new_capital}")
            QMessageBox.information(self, "成功", "资金更新成功")
        except ValueError:
            QMessageBox.critical(self, "错误", "请输入有效的资金金额")

    def _init_order_ui(self): 
        """下单页面初始化"""
        widget = QWidget()
        layout = QVBoxLayout(widget)

        # 品种选择下拉框
        product_layout = QHBoxLayout()
        product_label = QLabel("选择品种:")
        self.product_combo = QComboBox()
        # 初始化品种数据
        conn = connect_db()
        if conn:
            products = get_all_products(conn)
            for product in products:
                self.product_combo.addItem(product[1], product[2])  # 显示名称，存储交易所代码
            conn.close()
        product_layout.addWidget(product_label)
        product_layout.addWidget(self.product_combo)

        # 下单量输入框
        qty_layout = QHBoxLayout()
        qty_label = QLabel("下单量:")
        self.qty_input = QLineEdit("1")
        self.qty_input.setValidator(QIntValidator(1, 1000))
        qty_layout.addWidget(qty_label)
        qty_layout.addWidget(self.qty_input)

        # 下单方向选择
        direction_layout = QHBoxLayout()
        direction_label = QLabel("下单方向:")
        self.direction_combo = QComboBox()
        self.direction_combo.addItems(["买入", "卖出"])
        direction_layout.addWidget(direction_label)
        direction_layout.addWidget(self.direction_combo)

        # 下单按钮
        order_btn = QPushButton("下单")
        order_btn.clicked.connect(self._place_order)

        layout.addLayout(product_layout)
        layout.addLayout(qty_layout)
        layout.addLayout(direction_layout)
        layout.addWidget(order_btn)
        layout.addStretch()

        return widget

    def _place_order(self):
        """执行下单操作"""
        symbol = self.product_combo.currentData()
        qty = int(self.qty_input.text())
        direction = "BUY" if self.direction_combo.currentText() == "买入" else "SELL"

        try:
            if self.api:
                order = self.api.insert_order(
                    symbol=symbol,
                    direction=direction,
                    offset="OPEN",
                    volume=qty
                )
                QMessageBox.information(self, "成功", f"已提交 {direction} {symbol} {qty} 手的订单")
            else:
                QMessageBox.critical(self, "错误", "未连接到交易账户，请先连接")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"下单失败: {str(e)}")

    def _init_product_management_ui(self):
        """品种管理页面初始化"""
        widget = QWidget()
        layout = QVBoxLayout(widget)

        # 品种表格
        self.product_table = QTableWidget()
        self.product_table.setColumnCount(7)
        self.product_table.setHorizontalHeaderLabels(["ID", "品种名称", "交易所代码", "保证金", "止损点数", "止盈点数", "是否监控"])
        self.product_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self._refresh_product_table()

        # 操作按钮
        btn_layout = QHBoxLayout()
        add_btn = QPushButton("添加品种")
        add_btn.clicked.connect(self._add_product)
        edit_btn = QPushButton("编辑品种")
        edit_btn.clicked.connect(self._edit_product)
        delete_btn = QPushButton("删除品种")
        delete_btn.clicked.connect(self._delete_product)

        btn_layout.addWidget(add_btn)
        btn_layout.addWidget(edit_btn)
        btn_layout.addWidget(delete_btn)

        layout.addWidget(self.product_table)
        layout.addLayout(btn_layout)

        return widget

    def _refresh_product_table(self):
        """刷新品种表格数据"""
        conn = connect_db()
        if conn:
            products = get_all_products(conn)
            self.product_table.setRowCount(len(products))
            for row, product in enumerate(products):
                self.product_table.setItem(row, 0, QTableWidgetItem(str(product[0])))
                self.product_table.setItem(row, 1, QTableWidgetItem(product[1]))
                self.product_table.setItem(row, 2, QTableWidgetItem(product[2]))
                self.product_table.setItem(row, 3, QTableWidgetItem(str(product[3])))
                self.product_table.setItem(row, 4, QTableWidgetItem(str(product[4])))
                self.product_table.setItem(row, 5, QTableWidgetItem(str(product[5])))
                self.product_table.setItem(row, 6, QTableWidgetItem("是" if product[6] else "否"))
            conn.close()

    def _add_product(self):
        """添加品种对话框"""
        dialog = QDialog(self)
        dialog.setWindowTitle("添加品种")
        layout = QFormLayout(dialog)

        name_input = QLineEdit()
        exchange_input = QLineEdit()
        margin_input = QLineEdit()
        margin_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        stoploss_input = QLineEdit()
        stoploss_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        takeprofit_input = QLineEdit()
        takeprofit_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        monitored_check = QCheckBox()

        layout.addRow("品种名称:", name_input)
        layout.addRow("交易所代码:", exchange_input)
        layout.addRow("保证金:", margin_input)
        layout.addRow("止损点数:", stoploss_input)
        layout.addRow("止盈点数:", takeprofit_input)
        layout.addRow("是否监控:", monitored_check)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        if dialog.exec_() == QDialog.Accepted:
            try:
                conn = connect_db()
                if conn:
                    insert_product(
                        conn,
                        name_input.text(),
                        exchange_input.text(),
                        float(margin_input.text()),
                        float(stoploss_input.text()),
                        float(takeprofit_input.text()),
                        monitored_check.isChecked()
                    )
                    conn.close()
                    self._refresh_product_table()
                    QMessageBox.information(self, "成功", "品种添加成功")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"品种添加失败: {str(e)}")

    def _edit_product(self):
        """编辑品种对话框"""
        selected_row = self.product_table.currentRow()
        if selected_row == -1:
            QMessageBox.warning(self, "警告", "请先选择要编辑的品种")
            return

        product_id = int(self.product_table.item(selected_row, 0).text())
        dialog = QDialog(self)
        dialog.setWindowTitle("编辑品种")
        layout = QFormLayout(dialog)

        name_input = QLineEdit(self.product_table.item(selected_row, 1).text())
        exchange_input = QLineEdit(self.product_table.item(selected_row, 2).text())
        margin_input = QLineEdit(self.product_table.item(selected_row, 3).text())
        margin_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        stoploss_input = QLineEdit(self.product_table.item(selected_row, 4).text())
        stoploss_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        takeprofit_input = QLineEdit(self.product_table.item(selected_row, 5).text())
        takeprofit_input.setValidator(QDoubleValidator(0.0, 1e9, 2))
        monitored_check = QCheckBox()
        monitored_check.setChecked(self.product_table.item(selected_row, 6).text() == "是")

        layout.addRow("品种名称:", name_input)
        layout.addRow("交易所代码:", exchange_input)
        layout.addRow("保证金:", margin_input)
        layout.addRow("止损点数:", stoploss_input)
        layout.addRow("止盈点数:", takeprofit_input)
        layout.addRow("是否监控:", monitored_check)

        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(dialog.accept)
        button_box.rejected.connect(dialog.reject)
        layout.addWidget(button_box)

        if dialog.exec_() == QDialog.Accepted:
            try:
                conn = connect_db()
                if conn:
                    update_product(
                        conn,
                        product_id,
                        name_input.text(),
                        exchange_input.text(),
                        float(margin_input.text()),
                        float(stoploss_input.text()),
                        float(takeprofit_input.text()),
                        monitored_check.isChecked()
                    )
                    conn.close()
                    self._refresh_product_table()
                    QMessageBox.information(self, "成功", "品种编辑成功")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"品种编辑失败: {str(e)}")

    def _delete_product(self):
        """删除品种"""
        selected_row = self.product_table.currentRow()
        if selected_row == -1:
            QMessageBox.warning(self, "警告", "请先选择要删除的品种")
            return

        product_id = int(self.product_table.item(selected_row, 0).text())
        reply = QMessageBox.question(self, "确认", "确定要删除该品种吗？", QMessageBox.Yes | QMessageBox.No)
        if reply == QMessageBox.Yes:
            try:
                conn = connect_db()
                if conn:
                    delete_product(conn, product_id)
                    conn.close()
                    self._refresh_product_table()
                    QMessageBox.information(self, "成功", "品种删除成功")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"品种删除失败: {str(e)}")

    def _init_auto_sl_ui(self):
        """策略交易页面初始化"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(15, 15, 15, 15)

        # +++ 新增刷新按钮布局 +++
        btn_layout = QHBoxLayout()
        refresh_btn = QPushButton("刷新数据")
        refresh_btn.clicked.connect(self._refresh_strategy_table)  # 确保连接正确
        btn_layout.addWidget(refresh_btn)
        layout.addLayout(btn_layout)

        # 表格控件初始化
        self.strategy_table = QTableWidget()
        # 添加移动止盈止损周期列
        self.strategy_table.setColumnCount(9)
        self.strategy_table.setHorizontalHeaderLabels(["品种名称", "交易所代码", "保证金", "止损点数", "止盈点数", "限额止损", "移动止盈止损周期", "开仓方向", "是否监控"])
        self.strategy_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 启用按表头排序功能
        self.strategy_table.setSortingEnabled(True)

        # 初始化数据
        self._refresh_strategy_table()

        # 控制按钮区域
        control_layout = QVBoxLayout()

        # 策略开仓组
        open_group = QHBoxLayout()
        self.start_open_btn = QPushButton("启动策略开仓")
        self.start_open_btn.setCheckable(True)
        self.start_open_btn.setStyleSheet("""
            QPushButton {
                background-color: #f8f9fa;
                border: 1px solid #ced4da;
                border-radius: 4px;
                padding: 5px 10px;
                min-width: 120px;
            }
            QPushButton:checked {
                background-color: #dc3545;
                color: white;
                border-color: #dc3545;
            }
        """)

        # 策略平仓组
        close_group = QHBoxLayout()
        self.start_close_btn = QPushButton("启动策略平仓")
        self.start_close_btn.setCheckable(True)
        self.start_close_btn.setStyleSheet(self.start_open_btn.styleSheet())  # 复用相同样式

        # 策略平仓组
        open_close_group = QHBoxLayout()
        self.start_stp_close_btn = QPushButton("启动 自动止盈止损")
        self.start_stp_close_btn.setCheckable(True)
        self.start_stp_close_btn.setStyleSheet(self.start_open_btn.styleSheet())  # 复用相同样式

        # 下单量输入框
        self.open_qty = QLineEdit("1")
        self.open_qty.setValidator(QIntValidator(1, 1000))
        self.open_qty.setMaximumWidth(100)
        self.open_qty.setAlignment(Qt.AlignLeft)  # 左对齐

        # 调整布局结构
        open_group.addWidget(self.start_open_btn)
        open_group.addWidget(QLabel("下单量:"))
        open_group.addWidget(self.open_qty)
        open_group.addWidget(self.start_close_btn)  # 平仓按钮放到输入框右侧
        open_group.addWidget(self.start_stp_close_btn)
        open_group.addStretch()

        # 事件绑定
        self.start_open_btn.clicked.connect(lambda: self.toggle_strategy_open(" OPEN "))
        self.start_close_btn.clicked.connect(lambda: self.toggle_strategy_close(" CLOSE "))
        self.start_stp_close_btn.clicked.connect(lambda: self.toggle_strategy_stp_close(" STP || CLOSE "))

        # 组合布局
        control_layout.addLayout(open_group)
        control_layout.addLayout(close_group)
        control_layout.addLayout(open_close_group)

        layout.addLayout(btn_layout)  # 添加按钮布局
        layout.addWidget(self.strategy_table)
        layout.addLayout(control_layout)

        return widget

    def _init_help_ui(self):
        """帮助中心页面初始化"""
        help_widget = QWidget()
        main_layout = QVBoxLayout(help_widget)

        # 帮助文本部分
        help_text = QLabel("""
            欢迎使用资金管理系统！以下是一些使用指南：

            1. 计算下单量：在该页面输入相关参数，系统会自动计算合适的下单量。
            2. 下单：选择要交易的品种、下单量和方向，点击下单按钮即可提交订单。
            3. 品种管理：可以添加、编辑和删除交易品种，设置品种的相关参数。
            4. 全局设置：可以对系统的一些全局参数进行设置。
            5. 启动策略交易：可以启动策略开仓、平仓和自动止盈止损功能。
            6. 帮助中心：查看系统的使用指南和常见问题解答。

            如有任何问题，请联系技术支持。
        """)
        help_text.setWordWrap(True)
        main_layout.addWidget(help_text)

        return help_widget

    def _init_global_settings_ui(self):
        """全局设置页面初始化"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(15, 15, 15, 15)

        # 创建表格显示配置信息
        self.config_table = QTableWidget()
        self.config_table.setColumnCount(2)
        self.config_table.setHorizontalHeaderLabels(["配置项", "值"])
        self.config_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        # 启用按表头排序功能
        self.config_table.setSortingEnabled(True)

        # 初始化数据
        self._refresh_config_table()

        layout.addWidget(self.config_table)

        # 保存按钮
        save_btn = QPushButton("保存")
        save_btn.clicked.connect(self._save_configs)
        layout.addWidget(save_btn)

        # 返回按钮
        back_btn = QPushButton("返回")
        back_btn.clicked.connect(lambda: self.stacked_widget.setCurrentIndex(self.PAGE_INDEX["AUTO_SL"]))
        layout.addWidget(back_btn)

        return widget

    def _refresh_config_table(self):
        """刷新配置表格数据"""
        try:
            conn = sqlite3.connect('trade_monitor.db')
            cursor = conn.cursor()
            cursor.execute("SELECT key, value FROM config")
            configs = cursor.fetchall()
            self.config_table.setRowCount(len(configs))
            for row, (key, value) in enumerate(configs):
                self.config_table.setItem(row, 0, QTableWidgetItem(key))
                item = QTableWidgetItem(str(value))
                self.config_table.setItem(row, 1, item)
            conn.close()
        except Exception as e:
            QMessageBox.critical(self, "错误", f"获取配置信息失败: {str(e)}")

    def _save_configs(self):
        """保存配置信息到数据库"""
        try:
            conn = sqlite3.connect('trade_monitor.db')
            cursor = conn.cursor()
            for row in range(self.config_table.rowCount()):
                key = self.config_table.item(row, 0).text()
                value = self.config_table.item(row, 1).text()
                cursor.execute("UPDATE config SET value = ? WHERE key = ?", (value, key))
            conn.commit()
            conn.close()
            QMessageBox.information(self, "成功", "配置保存成功")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"保存配置信息失败: {str(e)}")

    def _refresh_strategy_table(self):
        """从数据库刷新策略表格数据"""
        conn = connect_db()
        if conn:
            products = get_monitored_products(conn)
            self.strategy_table.setColumnCount(9)  # 确保列数正确
            self.strategy_table.setHorizontalHeaderLabels(["品种名称", "交易所代码", "保证金", "止损点数", "止盈点数", "限额止损", "移动止盈止损周期", "开仓方向", "是否监控"])
            self.strategy_table.setRowCount(len(products))

            for row, product in enumerate(products):
                try:
                    self.strategy_table.setItem(row, 0, QTableWidgetItem(product[1]))
                    self.strategy_table.setItem(row, 1, QTableWidgetItem(product[2]))
                    self.strategy_table.setItem(row, 2, QTableWidgetItem(str(product[3])))
                    self.strategy_table.setItem(row, 3, QTableWidgetItem(f"{product[4]:.1f}"))
                    self.strategy_table.setItem(row, 4, QTableWidgetItem(f"{product[5]:.1f}"))
                    try:
                        limit_stoploss = float(product[6])
                        self.strategy_table.setItem(row, 5, QTableWidgetItem(f"{limit_stoploss:.2f}"))
                    except ValueError:
                        self.strategy_table.setItem(row, 5, QTableWidgetItem(str(product[6])))
                    self.strategy_table.setItem(row, 6, QTableWidgetItem(str(product[7])))  # 显示移动止盈止损周期
                    self.strategy_table.setItem(row, 7, QTableWidgetItem(product[8]))  # 显示开仓方向
                    self.strategy_table.setItem(row, 8, QTableWidgetItem("是" if product[9] else "否"))
                except IndexError as e:
                    print(f"填充表格时出错，行 {row}，错误信息: {e}")  # 添加错误处理
            conn.close()

    def toggle_strategy_open(self, strategy_type):
        """
        切换策略开仓状态
        参数：
            strategy_type: 策略类型字符串（当前版本固定为"OPEN"）
        功能：
            1. 控制策略开仓按钮的文本切换
            2. 管理策略启动/停止状态
        注意事项：
            - 按钮的选中状态通过isChecked()获取
            - 实际策略逻辑待后续实现
        """

        # 根据按钮选中状态更新界面显示
        if self.start_open_btn.isChecked():
            self.start_open_btn.setText(f"已启动策略{strategy_type} (单击停止)")  # 运行中状态显示
            print("启动策略开仓")
            # TODO: 此处添加实际启动策略的逻辑（例如创建策略线程）
        else:
            self.start_open_btn.setText(f"启动策略{strategy_type}")  # 默认状态显示
            print("已停止策略开仓")
            # TODO: 此处添加停止策略的逻辑（例如终止策略线程）

    def toggle_strategy_close(self, strategy_type):
        pass

    def toggle_strategy_stp_close(self, strategy_type):
        """切换策略状态"""
        print("启动 自动止盈止损")
        btn_open_close = self.start_stp_close_btn

        if btn_open_close.isChecked():
            if self.process_id is None:
                script_dir = os.path.dirname(os.path.abspath(__file__))
                self.exe_path = os.path.join(script_dir, "auto_stp10_stable04_01.exe")

            if not os.path.exists(self.exe_path):
                QMessageBox.critical(self, "错误", f"未找到程序: {self.exe_path}")
                return

            btn_open_close.setEnabled(False)  # 禁用按钮防止重复点击
            self.worker_thread = self.WorkerThread(self.exe_path)
            self.worker_thread.finished_signal.connect(self.on_thread_finished)
            self.worker_thread.start()
            # self.start_stp_close_btn.setEnabled(True)
            self.start_stp_close_btn.setText("正在启动 自动止盈止损")
            time.sleep(3)
            self.start_stp_close_btn.setEnabled(True)
            self.start_stp_close_btn.setText("停止 自动止盈止损")
        else:
            print("停止自动止盈止损")
            self.terminate_external_program("auto_stp10_stable04_01.exe")
            self.start_stp_close_btn.setText("启动 自动止盈止损")

    def setup_connections(self):
        pass

    def handle_page_change(self, index):
        pass

    def connect_tq(self):
        def connect_tq_worker():
            try:
                # 快期模拟账户
                tq_kq = TqKq()
                self.api = TqApi(account=tq_kq, auth=TqAuth("cps168", "alibaba"))
                self.macc = self.api.get_account()

                # 连接超时处理
                timeout = time.time() + 60  # 延长至20秒
                while not self.api or not self.macc:
                    # 这里 self.connect_btn 未定义，暂时注释
                    # self.connect_btn.setEnabled(False)
                    # self.connect_btn.setText("连接中...")
                    if time.time() > timeout:
                        raise TimeoutError("连接超时")

                if self.api and self.macc:
                    print("已经成功连接天勤账户")
                    print("当前账户可用资金：", self.macc.available)

                    # 修正f-string语法错误
                    self.update_signal.emit(f"{self.macc.available:.2f}")  # 新增

                    # 发射连接成功信号
                    self.connection_signal.emit("已连接 (点击断开)", True)

                    # 启动资金更新线程
                    Thread(target=self.update_capital, daemon=True).start()

            except Exception as e:
                self.connection_signal.emit(f"连接失败: {str(e)}", False)

        # 启动连接线程,用于避免阻塞主线程
        Thread(target=connect_tq_worker, daemon=True).start()

    def update_capital(self):
        """更新账户资金线程"""
        tm = time.time()
        while time.time() > tm:
            tm = time.time() + 60
            try:
                # 添加更完善的账户验证
                while self.api is None:
                    QMessageBox.critical(self, "错误", "未连接到天勤账户")

                # 主动查询账户信息（关键修复）
                account = self.api.get_account()
                _last_available = 0.0
                while True:
                    if account.available != _last_available:
                        self.update_signal.emit(f"{account.available:.2f}")
                        _last_available = account.available
            except Exception as e:
                print(f"更新异常: {str(e)}")

    def handle_connection(self, text, success):
        """处理连接状态更新"""
        # 这里 self.connect_btn 未定义，暂时注释
        # self.connect_btn.setText(text)
        # self.connect_btn.setEnabled(True)  # 确保按钮始终可点击
        if success:
            try:
                # self.connect_btn.clicked.disconnect()
                pass
            except TypeError:
                pass
            # 修改为直接绑定无需lambda
            # self.connect_btn.clicked.connect(self.disconnect_tq)
        else:
            try:
                # self.connect_btn.clicked.disconnect()
                pass
            except TypeError:
                pass
            # self.connect_btn.clicked.connect(self.connect_tq)
        QApplication.processEvents()

    def disconnect_tq(self):
        """断开天勤账户连接"""
        try:
            if self.api:
                # 等待最后一次更新完成
                # while self.api.register_update_notify():
                #     pass
                # 在主线程执行关闭操作
                # self.api.close()
                self.api = None
                self.tq_account = None
                # self.connect_btn.setText("连接天勤账户")
                # self.capital_input.clear()

                # 移除旧连接方式，直接调用connect_tq
                # self.connect_btn.clicked.disconnect()
                # self.connect_btn.clicked.connect(self.connect_tq)

                QMessageBox.information(self, "断开成功", "已断开天勤账户连接")

        except Exception as e:
            QMessageBox.critical(self, "断开错误", f"断开连接时发生错误: {str(e)}")

    def closeEvent(self, event):
        """重写关闭事件"""
        if self.api:
            reply = QMessageBox.question(self, "确认", "是否断开天勤账户连接？",
                                         QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
            if reply == QMessageBox.Yes:
                self.disconnect_tq()
        if hasattr(self, 'strategy_thread') and self.strategy_thread.is_alive():
            if self.api:
                self.api.close()
            self.strategy_thread.join(timeout=1)
        # print(self.process_id)
        if self.process_id is None:
            print("关闭策略")
            self.terminate_external_program("auto_stp10_stable04_01.exe")
        event.accept()

    def terminate_external_program(self, ExeName):
        try:
            # 使用 psutil 库
            for proc in psutil.process_iter(['name']):
                if proc.info['name'] == ExeName:
                    proc.terminate()
                    gone, still_alive = psutil.wait_procs([proc], timeout=5)
                    if still_alive:
                        for p in still_alive:
                            p.kill()
            print(f"使用 psutil 尝试终止 {ExeName}")
        except Exception as e:
            print(f"使用 psutil 终止 {ExeName} 失败: {e}")

        self.process_id = None

    # 添加缺失的信号定义
    update_signal = pyqtSignal(str)
    connection_signal = pyqtSignal(str, bool)

    class WorkerThread(QThread):
        finished_signal = pyqtSignal(bool)

        def __init__(self, exe_path, parent=None):
            super().__init__(parent)
            self.exe_path = exe_path
            self.process = None

        def run(self):
            try:
                self.process = subprocess.Popen(
                    [self.exe_path],
                    cwd=os.path.dirname(self.exe_path),
                    creationflags=subprocess.CREATE_NEW_CONSOLE
                )
                time.sleep(1)  # 等待程序启动
                self.minimize_exe_window()
                self.finished_signal.emit(True)
            except Exception as e:
                print(f"线程执行出错: {str(e)}")
                self.finished_signal.emit(False)

        def minimize_exe_window(self):
            """最小化外部程序窗口"""
            if self.process:
                start_time = time.time()
                while time.time() - start_time < 5:
                    try:
                        def callback(hwnd, extra):
                            if win32gui.IsWindowVisible(hwnd):
                                _, pid = win32process.GetWindowThreadProcessId(hwnd)
                                if pid == self.process.pid:
                                    win32gui.ShowWindow(hwnd, win32con.SW_MINIMIZE)
                                    return False
                            return True

                        win32gui.EnumWindows(callback, None)
                        break
                    except:
                        time.sleep(0.5)

    def on_thread_finished(self, success):
        # self.start_stp_close_btn.setEnabled(True)
        if success:
            self.process_id = self.worker_thread.process.pid

        else:
            QMessageBox.critical(self, "错误", "启动外部程序失败")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = CapitalManager()
    window.show()
    sys.exit(app.exec_())